﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace Memory
{
    public partial class MemoryForm : Form
    {
        public const int Columns = 6;
        public const int Rows = 4;
        public const int BackgroundIndex = 0;
        private Random random;

        private List<int> indexes = new List<int>();
        private List<Image> images = new List<Image>();

        private const string ImageCategory = "images";
        private Common.Resource resource = new Common.Resource();
        private TButton openButton = null;

        public MemoryForm()
        {
            this.random = new Random(DateTime.Now.Millisecond);

            InitializeComponent();

            int ratio = this.ClientRectangle.Width / 3;
            int diff = this.Size.Height - this.ClientRectangle.Height;
            this.Size = new Size(this.Size.Width, ratio * 2 + diff);

            resource.Levels = 4;

            for (int i = 1; i < (MemoryForm.Columns * MemoryForm.Rows / 2) + 1; i++)
            {
                indexes.Add(i);
                indexes.Add(i);
            }

            this.LoadImages();

            Common.LayoutHelper.CreateControlsToFillClientArea(this, new Size(MemoryForm.Columns, MemoryForm.Rows), this.CreateButton);
        }

        private void LoadImages()
        {
            string [] images = { "back.png", "dart.png", "disc.png", "frida.png", "horizon.png", "jeans.png", "lego.png", "magnus.png", "mailbox.png", "nisse.png", "palm.png", "rose.png", "snack.png" };

            foreach (string filename in images)
            {
                this.images.Add(this.resource.GetBitmap(filename, MemoryForm.ImageCategory));
            }
        }

        public TButton CreateButton(int x, int y)
        {
            int index = this.random.Next(this.indexes.Count);
            int imageIndex = this.indexes[index];
            this.indexes.RemoveAt(index);
            return new TButton(new Point(x, y), this, imageIndex);
        }

        public List<Image> Images
        {
            get
            {
                return this.images;
            }
        }

        public void Open(TButton button)
        {
            if (openButton == null)
            {
                openButton = button;
                foreach (Control control in this.Controls)
                {
                    TButton buttonToClose = control as TButton;
                    buttonToClose.Close();
                }
            }
            else
            {
                if (button != openButton)
                {
                    if (openButton.Index == button.Index)
                    {
                        openButton.Lock();
                        button.Lock();

                        if (this.IsGameFinished())
                        {
                            Common.TransparentButton endGame = new Common.TransparentButton();
                            endGame.Location = new Point(0, 0);
                            endGame.Size = this.ClientRectangle.Size;
                            endGame.BackColor = Color.Transparent;
                            endGame.Click += new EventHandler(endGame_Click);
                            endGame.Font = new Font(FontFamily.GenericSansSerif, 16, FontStyle.Bold);
                            endGame.Text = "Game Finished. Click to Exit.";
                            this.Controls.Add(endGame);
                            endGame.BringToFront();
                        }
                    }
                    openButton = null;
                }
            }
        }

        void endGame_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        public bool IsGameFinished()
        {
            foreach (Control control in this.Controls)
            {
                TButton button = control as TButton;
                if (!button.IsLocked)
                {
                    return false;
                }
            }

            return true;
        }
    }
}
